home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 1 / The 640 Meg Shareware Studio CD-ROM Volume I (Data Express)(1992).ISO / driver / macpab2.dsk / MACPA2.ZIP / MAAPI / PLAY.C < prev    next >
C/C++ Source or Header  |  1992-06-30  |  35KB  |  702 lines

  1. /*********************************************************************/
  2. /*                                     */
  3. /*  MODULE NAME = PLAY.C                         */
  4. /*                                     */
  5. /*  DESCRIPTIVE NAME = Audio Application Programming Interface         */
  6. /*               Sample Play Program                 */
  7. /*                                     */
  8. /*  COPYRIGHT = (C) Copyright by IBM Corp. 1989, 1991.             */
  9. /*        All rights reserved.                     */
  10. /*        Refer to "LICENSE.DOC" for information regarding     */
  11. /*        the use of this file.                     */
  12. /*                                     */
  13. /*  FUNCTION = Provides the following functions/tools:             */
  14. /*                                     */
  15. /*           play - Provides a simple working example of         */
  16. /*              playing using the AVC Audio API.             */
  17. /*                                     */
  18. /*  CONVENTIONS = See Below                         */
  19. /*                                     */
  20. /*    Constants - upper case                         */
  21. /*    Internal variables - lower case                     */
  22. /*    External variables - as required                     */
  23. /*    Internal functions - initial caps                  */
  24. /*    External functions - as required                     */
  25. /*                                     */
  26. /*                                     */
  27. /*  CHANGE ACTIVITY =  See Below                     */
  28. /*                                     */
  29. /*               01/11/90, AVC Release 1.02             */
  30. /*               07/02/90, AVC Release 1.03             */
  31. /*             Added MIDI error message             */
  32. /*               01/25/91, M-ACPA Release 2.0             */
  33. /*             Added RIFF WAVE file and source mix support */
  34. /*                                     */
  35. /*********************************************************************/
  36. /*                                     */
  37. /*************************SYSTEM INCLUDES*****************************/
  38. /*                                     */
  39. #define LINT_ARGS               /* Perform type checking on   */
  40.                        /*  library functions         */
  41. /*                                     */
  42. /*                                     */
  43. #include <fcntl.h>               /*                 */
  44. #include <sys\types.h>               /*                 */
  45. #include <sys\stat.h>               /*                 */
  46. #include <conio.h>               /*                 */
  47. #include <io.h>                /*                 */
  48. #include <stdio.h>               /*                 */
  49. #include <errno.h>               /*                 */
  50. #include <stdlib.h>               /*                 */
  51. #include <string.h>               /*                 */
  52. #include <time.h>               /*                 */
  53. #include <malloc.h>               /*                 */
  54. /*                                     */
  55. /**************************AAPI INCLUDES******************************/
  56. /*                                     */
  57. #include "play.h"                      /* Program messages           */
  58. #include "eapidbas.cnc"                /* Audio file structures      */
  59. #include "eapiacb.cnc"                 /* Audio constants/declares   */
  60. /*                                     */
  61. /*********************CONSTANT DEFINITIONS****************************/
  62. /*                                     */
  63. #define TRUE            1      /* True constant          */
  64. #define FALSE            0      /* False constant         */
  65. #define SUCCESS         0      /* Function call successful   */
  66. /*                                     */
  67. #define AVC_EXT  "._AU"                /* AVC audio file extension   */
  68. #define RIFF_EXT ".WAV"                /* RIFF Audio file extension  */
  69. /*                                     */
  70. /*****************VARIABLE DECLARATION/DEFINITIONS********************/
  71. /*                                     */
  72. short     master_volume     =    100;    /* Default volume and          */
  73. short     track_1_volume  =    100;    /*  balance settings          */
  74. short     track_1_rate     =     0;    /*                  */
  75. short     balance     =     50;    /*                  */
  76. short     balance_rate     =     0;    /*                  */
  77. char huge *lalloc    =    NULL;  /* Ptr to data buffer > 64K   */
  78. unsigned long buf_time;            /* Size of data buffers in    */
  79.                        /*  milliseconds          */
  80. /*                                     */
  81. /******************RESIDENT FUNCTION DECLARATIONS*********************/
  82. /*                                     */
  83. static void Get_File_Name(char *);     /* Get output file name         */
  84. /*                                     */
  85. static short Init_ACB(AAPI_ACB *,      /* Initialize Audio Control   */
  86.  FAB_STRUCT*,AAPI_FMT*,unsigned short);/*  Block             */
  87. /*                                     */
  88. static short Check_IO(AAPI_ACB *);     /* Check if I/O needed         */
  89. /*                                     */
  90. static void Write_Error_Message(short);/* Put error message to screen*/
  91. /*                                     */
  92. static void Query_Settings();           /* Query user for settings    */
  93. /*                                     */
  94. /*********************************************************************/
  95. /*                                     */
  96. /*********************************************************************/
  97. /*********************************************************************/
  98. /*********************************************************************/
  99. /*                                     */
  100. /* FUNCTION NAME = play                          */
  101. /*                                     */
  102. /* FUNCTION = Initializes the audio card and opens an audio file     */
  103. /*          and begins reading and playing audio data.         */
  104. /*                                     */
  105. /* INPUT =    None - The user is prompted for the name of a file     */
  106. /*          that contains the input audio data.  The user is         */
  107. /*          also prompted for the initial volume and balance         */
  108. /*          controls.                          */
  109. /*                                     */
  110. /*          The file must exist and be one of the following         */
  111. /*           types of audio files:                     */
  112. /*                                     */
  113. /*          - AVC                             */
  114. /*          - RIFF WAVE                         */
  115. /*                                     */
  116. /*          If no extension is used the default AVC extension      */
  117. /*          of _AU is appended to the name.                 */
  118. /*                                     */
  119. /*          If no file name is inputted the default is to use      */
  120. /*          the "source mix" capability.  This allows control      */
  121. /*          of the M-ACPA input source as if it were a PCM file.   */
  122. /*                                     */
  123. /*          User hits any key to stop operation.             */
  124. /*                                     */
  125. /* OUTPUT =   If successful                         */
  126. /*        Audio file contents played until user hits any key   */
  127. /*                                     */
  128. /*          Else error message written to screen             */
  129. /*                                     */
  130. /*********************************************************************/
  131. /*********************************************************************/
  132. /*                PDL                     */
  133. /*********************************************************************/
  134. /*********************************************************************/
  135. /* 010 MAIN FUNCTION                             */
  136. /* 020 | Get an audio file name from the user                 */
  137. /* 030 | Determine the type of file (AVC, RIFF WAVE)             */
  138. /* 040 | IF no error, THEN                         */
  139. /* 050 | | CALL the AAPI to open and initialize the audio file         */
  140. /* +   | |    and any associated objects                 */
  141. /* 060 | ENDIF                                 */
  142. /* 070 | IF no error, THEN                         */
  143. /* 080 | | Query the user for volume and balance settings         */
  144. /* 090 | | Initialize the Audio Control Block for playing         */
  145. /* 100 | | IF no error, THEN                         */
  146. /* 110 | | | CALL the AAPI to set up the play operation          */
  147. /* 120 | | ENDIF                             */
  148. /* 130 | | IF no error, THEN                         */
  149. /* 140 | | | CALL the AAPI to start playing                 */
  150. /* 150 | | | IF no error, THEN                         */
  151. /* +   | | | | (The AAPI is now running in the background.  The      */
  152. /* +   | | | |    application can now monitor the AAPI or do whatever  */
  153. /* +   | | | |    application specific work that needs to be done.     */
  154. /* +   | | | |    This program has no real work to do so it will sit   */
  155. /* +   | | | |    in a loop waiting for the user to hit a key.         */
  156. /* +   | | | |    The AAPI will do file I/O and keep the card playing  */
  157. /* +   | | | |    until there is no more audio data in the file         */
  158. /* +   | | | |    or it hits the stop point you requested.         */
  159. /* +   | | | |    You can stop it at any point or after it         */
  160. /* +   | | | |    has run out of data.  You can control things like    */
  161. /* +   | | | |    volume and balance while it is playing by doing      */
  162. /* +   | | | |    "audio control" calls.)                              */
  163. /* 160 | | | | WHILE user has not quit (hit any key)             */
  164. /* +   | | | | |      and still playing successfully             */
  165. /* 170 | | | | | Write elapsed time to screen                 */
  166. /* 180 | | | | | Check if I/O needed for card.                 */
  167. /* +   | | | | | (This is optional.  The AAPI will do this for you   */
  168. /* +   | | | | |  if you don't request that file I/O be done.        */
  169. /* +   | | | | |  One reason you might want to control when I/O is   */
  170. /* +   | | | | |  done is if you are writing (dissolving) images to  */
  171. /* +   | | | | |  the screen and you want this to look smooth not    */
  172. /* +   | | | | |  jerky. You can request that I/O be done just         */
  173. /* +   | | | | |  before you begin the dissolve so that no I/O is    */
  174. /* +   | | | | |  done during the dissolve to disrupt it. When         */
  175. /* +   | | | | |  playing high data rate audio (> 44KBS) it may      */
  176. /* +   | | | | |  always be necessary to make this call).         */
  177. /* 190 | | | | ENDDO                             */
  178. /* 200 | | | | Check background return code                 */
  179. /* 210 | | | | IF not already stopped, THEN                 */
  180. /* 220 | | | | | CALL the AAPI to stop playing immediately         */
  181. /* 230 | | | | | Wait for stop to complete                 */
  182. /* 240 | | | | ENDIF                             */
  183. /* 250 | | | ENDIF                             */
  184. /* 260 | | ENDIF                             */
  185. /* 270 | | IF AAPI was initialized, THEN                 */
  186. /* 280 | | | CALL the AAPI to terminate audio operation          */
  187. /* 290 | | ENDIF                             */
  188. /* 300 | | IF file was opened, THEN                     */
  189. /* 310 | | | CALL the AAPI to close the audio file and             */
  190. /* +   | | |   deallocate the associated audio objects             */
  191. /* 320 | | ENDIF                             */
  192. /* 330 | | IF data buffer allocated, THEN                 */
  193. /* 340 | | | Free the buffer                         */
  194. /* 350 | | ENDIF                             */
  195. /* 360 | ENDIF                                 */
  196. /* 370 | IF error occurred, THEN                     */
  197. /* 380 | | Write the appropriate error message to user             */
  198. /* 390 | ENDIF                                 */
  199. /* 400 ENDFUNCTION MAIN                          */
  200. /*********************************************************************/
  201. /*                                     */
  202. /*********************************************************************/
  203. /*********************************************************************/
  204. /*                   CODE                     */
  205. /*********************************************************************/
  206. /*********************************************************************/
  207. main()                       /* 010 Begin Function         */
  208. {                       /* 010                 */
  209. /********************LOCAL VARIABLE DEFINITIONS***********************/
  210. short rc;                   /* Return code             */
  211. char aname[81];                /* Audio file name         */
  212. FAB_STRUCT *fabp;               /* Ptr to File Access Block   */
  213. AAPI_ACB   acb;                /* Audio Control Block         */
  214. short cur_pos;                   /* Current position (seconds) */
  215. long stime;                   /* Wait time start         */
  216. short  w;                   /* Wait loop index         */
  217. short  close_file;               /* File needs to be closed    */
  218. short  term_audio;               /* AAPI need to be terminated */
  219. unsigned short    type;               /* File type to play         */
  220. AAPI_FMT fmt;                   /* PCM format data         */
  221. /*********************************************************************/
  222.   cprintf(M_22); cprintf(M_23);        /* 020 Program title         */
  223.   close_file = FALSE;               /* 020 No open file yet         */
  224.   term_audio = FALSE;               /* 020 Audio not initialized  */
  225.   Get_File_Name(aname);            /* 020 Get name of audio file */
  226.   rc = fab_type(aname,&type);           /* 030 Find out its type      */
  227.   if (rc == SUCCESS)               /* 040 If no error         */
  228.   {                       /* 040                 */
  229.     switch (type)               /* 050 Case of file type      */
  230.     {                       /* 050                 */
  231.       case AAFB_AVCF  :            /* 050 AVC             */
  232.       rc = fab_open(aname,           /* 050 Call AAPI file function*/
  233.          AAFB_OPEN,AAFB_EXNO,0,    /* 050  to initialize file and*/
  234.          &fabp,0,0,0,0);           /* 050  associated structures */
  235.       break;                   /* 050                 */
  236.       case AAFB_WAVE  :            /* 050 RIFF WAVE          */
  237.       rc = fab_ropn(aname,           /* 050                 */
  238.          AAFB_OPEN,&fabp,&fmt);    /* 050                 */
  239.       break;                   /* 050                 */
  240.       case AAFB_NONE  :            /* 050 File does not exist    */
  241.       rc = AAFB_RC_02;               /* 050                 */
  242.       break;                   /* 050                 */
  243.       case AAFB_UKNW  :            /* 050 Unknown file type      */
  244.       default :                /* 050 Else case          */
  245.       rc = AAFB_RC_07;               /* 050                 */
  246.       break;                   /* 050                 */
  247.     }                       /* 050 End Switch         */
  248.   }                       /* 060                 */
  249.   if (rc == SUCCESS)               /* 070 If no error opening    */
  250.   {                       /* 070  the audio file         */
  251.     close_file = TRUE;               /* 080 Remember to close file */
  252.     Query_Settings();               /* 080 Get user vol/bal         */
  253.     rc = Init_ACB(&acb,fabp,&fmt,type);/* 090 Initialize Audio CB    */
  254.     if (rc == SUCCESS)               /* 100 If no error         */
  255.     {                       /* 100                 */
  256.       rc = aud_set(&acb);           /* 110 Set up audio operation */
  257.     }                       /* 120                 */
  258.     if (rc == SUCCESS)               /* 130 If no error on set up  */
  259.     {                       /* 130                 */
  260.       buf_time = acb.timeleft >= 100L  /* 140 Save max time before   */
  261.     ? acb.timeleft : 100L;           /* 140  I/O is required         */
  262.       term_audio = TRUE;           /* 140 Audio is initialized   */
  263.       cprintf(M_2);               /* 140 Tell user how to stop  */
  264.       cprintf(M_14,0);               /* 140  and current position  */
  265.       rc = aud_strt(&acb);           /* 140 Start playing         */
  266.       if (rc==SUCCESS)               /* 150 If started playing     */
  267.       {                    /* 150                 */
  268.     cur_pos = acb.position/1000L;  /* 160 Nothing played yet     */
  269.     while ((!kbhit()) &&           /* 160 While user hasn't quit */
  270.       (acb.state==AAPI_PLAYING) && /* 160  and still playing     */
  271.       (rc == SUCCESS))           /* 160  and no errors yet     */
  272.     {                   /* 160                 */
  273.       if((short)(acb.position      /* 170 If playing next second */
  274.          /1000L) > cur_pos)        /* 170  yet             */
  275.       {                   /* 170                 */
  276.         cur_pos++;               /* 170 Tell user elapsed time */
  277.         cprintf(M_14,cur_pos);     /* 170  in seconds         */
  278.       }                   /* 170                 */
  279.       for(w=0;w<=4000;w++);        /* 170 Don't badger OS        */
  280.       rc = Check_IO(&acb);           /* 180 Optional call to         */
  281.                        /* 180  request I/O. If high  */
  282.                        /* 180  data rate PCM is      */
  283.                        /* 180  being played then this*/
  284.                        /* 180  call should be done.  */
  285.     }                   /* 190 Enddo             */
  286.     if (acb.state != AAPI_STOPPED) /* 210 If not already stopped */
  287.     {                   /* 210                 */
  288.       acb.controls = AAPI_STOP;    /* 220 Set stop position so   */
  289.       acb.stoppos  = 0L;           /* 220  an immediate stop     */
  290.       acb.ctlparms = AAPI_STPI;    /* 220  will be executed      */
  291.       aud_ctrl(&acb);           /* 220 Execute the stop         */
  292.       stime = clock();           /* 230 Wait for stop to         */
  293.       while(               /* 230  complete before         */
  294.       (acb.state!=AAPI_STOPPED) && /* 230  continuing, do not    */
  295.       ((clock() - stime) < 30000)) /* 230  badger OS while         */
  296.       for(w=0;w<=1000;w++);        /* 230  waiting             */
  297.     }                   /* 240                 */
  298.     if ((rc == SUCCESS) &&           /* 200 If an error occurred   */
  299.          (acb.backrc != SUCCESS))  /* 200  in background while   */
  300.     {                   /* 200  playing             */
  301.        rc = acb.backrc;           /* 200 Tell caller         */
  302.     }                   /* 200                 */
  303.       }                    /* 250                 */
  304.     }                       /* 260                 */
  305.     if (term_audio)               /* 270 If no error occurred   */
  306.     {                       /* 270                 */
  307.       aud_term(&acb);               /* 280 Terminate AAPI         */
  308.     }                       /* 290                 */
  309.     if (close_file)               /* 300 If file was opened     */
  310.     {                       /* 300                 */
  311.       fab_close(fabp);               /* 310 Close audio file         */
  312.     }                       /* 320                 */
  313.     if (lalloc != NULL)            /* 330 If allocated buffer    */
  314.     {                       /* 330                 */
  315.       hfree(lalloc);               /* 340 Free it             */
  316.     }                       /* 350                 */
  317.   }                       /* 360                 */
  318.   if (rc != SUCCESS)               /* 370 If error occurred      */
  319.   {                       /* 370                 */
  320.     Write_Error_Message(rc);           /* 380 Tell user          */
  321.   }                       /* 390                 */
  322. }                       /* 400 End Function         */
  323. /*********************************************************************/
  324. /*                                     */
  325. /*********************************************************************/
  326. /*********************************************************************/
  327. /*********************************************************************/
  328. /*                                     */
  329. /* FUNCTION NAME = Init_ACB                         */
  330. /*                                     */
  331. /* FUNCTION = Initialize the Audio Control Block (ACB) for a         */
  332. /*          play operation.                         */
  333. /*                                     */
  334. /* INPUT =    Ptr to ACB                         */
  335. /*          Ptr to FAB                         */
  336. /*                                     */
  337. /* OUTPUT =   0/ Success - ACB initialized for use             */
  338. /*       3224/ Failed - No audio device installed             */
  339. /*       3225/ Failed - Audio device installed, but ints disabled  */
  340. /*       3226/ Failed - Device driver not responding (OS/2 only)   */
  341. /*                                     */
  342. /*********************************************************************/
  343. /*********************************************************************/
  344. /*                PDL                     */
  345. /*********************************************************************/
  346. /*********************************************************************/
  347. /* 010 Init_ACB FUNCTION                         */
  348. /* 020 | CALL AAPI to initialize Audio Control Block             */
  349. /* 030 | Set ACB fields needed for playing operation             */
  350. /* 040 | Allocate and pass data buffers to AAPI              */
  351. /* 050 | IF no error, THEN                         */
  352. /* 060 | | Call AAPI to get the current hardware configuration         */
  353. /* 070 | ELSE out of memory                         */
  354. /* 080 | | Tell caller                             */
  355. /* 090 | ENDIF                                 */
  356. /* 100 | IF valid configuration and card/device driver responding    */
  357. /* 110 | | Put configuration information into ACB fields         */
  358. /* 120 | ENDIF                                 */
  359. /* 130 | RETURN result to caller                     */
  360. /* 140 ENDFUNCTION Init_ACB                         */
  361. /*********************************************************************/
  362. /*                                     */
  363. /*********************************************************************/
  364. /*********************************************************************/
  365. /*                   CODE                     */
  366. /*********************************************************************/
  367. /*********************************************************************/
  368. static short Init_ACB(acbp,fabp,fmtp,  /* 010 Begin Function         */
  369.                   type)    /*                 */
  370. AAPI_ACB  *acbp;               /* Audio Control Block         */
  371. FAB_STRUCT *fabp;               /* Ptr to File Access Block   */
  372. AAPI_FMT *fmtp;                /* Ptr to PCM format info     */
  373. unsigned short type;               /* Type of file requested     */
  374. {                       /* 010                 */
  375. /********************LOCAL VARIABLE DEFINITIONS***********************/
  376. short         rc;               /* Return code             */
  377. AAPI_DEV   adcb;               /* Audio Device Control Block */
  378. short i;                   /* Loop index             */
  379. /*********************************************************************/
  380.   acbp->acb2ptr = 0L;               /* 020 No secondary ACB         */
  381.   aud_init(acbp);               /* 020 Initialize control blk */
  382.   acbp->channel  = AAPI_CHNS;           /* 030 Set input channel      */
  383.   acbp->dspmode  = AAPI_PLAY;           /* 030 Operation is playing   */
  384.   acbp->seektype = AAPI_INIT;           /* 030 First call this file   */
  385.   acbp->controls = AAPI_MVOL+AAPI_TVO1 /* 030 Set for volume and     */
  386.                +AAPI_CBAL; /* 030  balance changes         */
  387.   acbp->masvol     = master_volume;      /* 030 Set master volume,     */
  388.   acbp->trkvol1  = track_1_volume;     /* 030      track volume         */
  389.   acbp->trkvol1s = 0;               /* 030      with fade request, */
  390.   acbp->trkvol1e = track_1_rate;       /* 030                 */
  391.   acbp->chnbal     = balance;           /* 030      balance with         */
  392.   acbp->chnbals  = 0;               /* 030      fade request         */
  393.   acbp->chnbale  = balance_rate;       /* 030                 */
  394.   acbp->outchan  = AAPI_OTAB;           /* 030                 */
  395.   acbp->oprparms = 0;               /* 030 No operation controls  */
  396.   acbp->fileptr  = fabp;           /* 030 Ptr to FAB (file info) */
  397.   acbp->subtype  = 0;               /* 030 Subtype to use         */
  398.   acbp->audstart = 0L;               /* 030 Start at beginning     */
  399.   acbp->audend     = 0L;               /* 030 No stop position         */
  400.   acbp->fmtptr     = (type == AAFB_WAVE) /* 030 Pass additional PCM    */
  401.            ? fmtp : NULL;      /* 030  info if doing PCM     */
  402.   acbp->memid     = AAPI_MAIN;           /* 040 Pass an IO buffer      */
  403.   if ((type == AAFB_WAVE) &&           /* 040 If doing high data     */
  404.       ((fmtp->samples_per_second *     /* 040  rate PCM, then         */
  405.     (unsigned long)fmtp->channels* /* 040  allocate large buffers*/
  406.     (unsigned long)            /* 040  else use 64K         */
  407.     (fmtp->bits_per_sample/8)) >   /* 040                 */
  408.      AAPI_FMT_44KH_W))           /* 040                 */
  409.   {                       /* 040                 */
  410.                        /* 040 Buffrs can be allocated*/
  411.                        /* 040  from 0-64K and then   */
  412.                        /* 040  in 64K increments     */
  413.                        /* 040                 */
  414.     #ifdef O_2                   /* 040 If in OS/2         */
  415.     acbp->bufflen  = 0X100000L;        /* 040 Allocate 1 meg buffer  */
  416.     #else                   /* 040 Else in DOS         */
  417.     acbp->bufflen  = 0X40000L;           /* 040 Allocate 256 K buffer  */
  418.     #endif                   /* 040                 */
  419.   }                       /* 040                 */
  420.   else                       /* 040 Else low data rate file*/
  421.   {                       /* 040                 */
  422.     acbp->bufflen  = 0X10000L;           /* 040 Allocate 64 K buffer   */
  423.   }                       /* 040                 */
  424.   for(i=0;(i<=2)&&(!lalloc);i++)       /* 040 Make three attempts to */
  425.   {                       /* 040  allocate the buffer   */
  426.     lalloc = (char huge *)           /* 040                 */
  427.     halloc(acbp->bufflen,sizeof(char));/* 040                 */
  428.     if    (lalloc == NULL)           /* 040 If not enough memory   */
  429.     {                       /* 040                 */
  430.       acbp->bufflen /=2L;           /* 040 Try asking for half    */
  431.     }                       /* 040                 */
  432.   }                       /* 040                 */
  433.   acbp->buffptr = (unsigned char *)    /* 040                 */
  434.           lalloc;           /* 040                 */
  435.   if (lalloc != NULL)               /* 050 If allocated buffer    */
  436.   {                       /* 050                 */
  437.     rc = aud_cfig(&adcb);           /* 060 Get hardware config    */
  438.   }                       /* 070                 */
  439.   else                       /* 070 Else tell caller         */
  440.   {                       /* 070                 */
  441.     rc = AAPI_RC_13;               /* 080 Not enough memory      */
  442.   }                       /* 090 Endif             */
  443.   if (rc == SUCCESS)               /* 100 If card is installed   */
  444.   {                       /* 100  and active         */
  445.     acbp->intlevel = (unsigned char)   /* 110 Set interrupt level    */
  446.              adcb.intlev;      /* 110                 */
  447.     acbp->piobase  = adcb.iobase;      /* 110  and PIO base address  */
  448.   }                       /* 120                 */
  449.   return(rc);                   /* 130 Return result to caller*/
  450. }                       /* 140 End Function         */
  451. /*********************************************************************/
  452. /*                                     */
  453. /*********************************************************************/
  454. /*********************************************************************/
  455. /*********************************************************************/
  456. /*                                     */
  457. /* FUNCTION NAME = Check I/O                         */
  458. /*                                     */
  459. /* FUNCTION = If over half the I/O buffer is empty then queue a      */
  460. /*          command to do I/O to fill audio data buffer.         */
  461. /*                                     */
  462. /* INPUT =  Ptr to ACB                             */
  463. /*                                     */
  464. /* OUTPUT =   0/ Success                         */
  465. /*       3207/ Error on file read                     */
  466. /*       3211/ Error on file seek                     */
  467. /*       3220/ Error on file write                     */
  468. /*                                     */
  469. /*********************************************************************/
  470. /*********************************************************************/
  471. /*                   CODE                     */
  472. /*********************************************************************/
  473. /*********************************************************************/
  474. static short Check_IO(acbp)           /* Begin Function         */
  475. AAPI_ACB  *acbp;               /* Audio Control Block         */
  476. {                       /*                 */
  477. /********************LOCAL VARIABLE DEFINITIONS***********************/
  478. short rc;                   /* Return code             */
  479. /*********************************************************************/
  480.   rc =    SUCCESS;               /*                 */
  481.   if (acbp->timeleft <= (buf_time/2L)) /* If data buffers is at      */
  482.   {                       /*  least half empty         */
  483.     acbp->controls = AAPI_PFIO;        /* Set to do I/O only         */
  484.     acbp->iotime = 0;               /* Set maximum amount         */
  485.     rc = aud_ctrl(acbp);           /* Execute the controls         */
  486.     if ((rc == AAPI_RC_17) ||           /* If I/O not ready, or         */
  487.     (rc == AAPI_RC_20))           /*   ctrl ignored, Then         */
  488.     {                       /*                 */
  489.       rc = SUCCESS;               /* Non-fatal error         */
  490.     }                       /*                 */
  491.   }                       /*                 */
  492.   return(rc);                   /* Return to caller         */
  493. }                       /* End Function             */
  494. /*********************************************************************/
  495. /*                                     */
  496. /*********************************************************************/
  497. /*********************************************************************/
  498. /*********************************************************************/
  499. /*                                     */
  500. /* FUNCTION NAME = Get_File_Name                     */
  501. /*                                     */
  502. /* FUNCTION = Query user for audio file name. Append default         */
  503. /*          AVC extension if no extension if given.             */
  504. /*          If no name was typed, then the default is the Source   */
  505. /*          Mix device.                         */
  506. /*                                     */
  507. /* INPUT =    Ptr to area for name                     */
  508. /*                                     */
  509. /* OUTPUT =   None - name returned in callers area             */
  510. /*                                     */
  511. /*********************************************************************/
  512. /*********************************************************************/
  513. /*                   CODE                     */
  514. /*********************************************************************/
  515. /*********************************************************************/
  516. static void Get_File_Name(name)        /* Begin Function         */
  517. char *name;                   /* Audio File name         */
  518. {                       /*                 */
  519. /********************LOCAL VARIABLE DEFINITIONS***********************/
  520. char *end;                   /* Ptr to end of name         */
  521. char input_buffer[80];               /*                 */
  522. /*********************************************************************/
  523.   cprintf(M_1);                /* Query and get the         */
  524.   gets(input_buffer);               /*  file name             */
  525.   if(sscanf(input_buffer,"%s",name)    /* If name was typed          */
  526.      ==1)                   /*                 */
  527.   {                       /*                 */
  528.     if(!(((end=strrchr(name,'.'))      /* If name has no             */
  529.       !=0) &&                   /*  extension             */
  530.       (strrchr(end,'\\')==0)))         /*                            */
  531.     {                       /*                 */
  532.       if(access(name,0) != SUCCESS)    /* Check for existance         */
  533.       {                    /* If not found try RIFF      */
  534.     strcat(name,RIFF_EXT);           /*  extension             */
  535.     if(access(name,0) != SUCCESS)  /* Check for existance         */
  536.     {                   /* If not found try AVC         */
  537.       strcpy(&name[strlen(name)    /*  extension             */
  538.        -4],AVC_EXT);           /*                 */
  539.     }                   /*                 */
  540.       }                    /*                 */
  541.     }                       /*                 */
  542.   }                       /*                 */
  543.   else                       /* Else user hit enter asking */
  544.   {                       /*  for Source Mix         */
  545.     strcpy(name,AAFB_SMIX);           /* Use source mix device name */
  546.   }                       /*                 */
  547.   return;                   /* Return result to caller    */
  548. }                       /* End Function             */
  549. /*********************************************************************/
  550. /*                                     */
  551. /*********************************************************************/
  552. /*********************************************************************/
  553. /*********************************************************************/
  554. /*                                     */
  555. /* FUNCTION NAME = Query_Settings                     */
  556. /*                                     */
  557. /* FUNCTION = Query user for volume and balance settings.         */
  558. /*                                     */
  559. /* INPUT =    None                             */
  560. /*                                     */
  561. /* OUTPUT =   None                             */
  562. /*                                     */
  563. /*********************************************************************/
  564. /*********************************************************************/
  565. /*                   CODE                     */
  566. /*********************************************************************/
  567. /*********************************************************************/
  568. static void Query_Settings()           /* Begin Function         */
  569. {                       /*                 */
  570. /********************LOCAL VARIABLE DEFINITIONS***********************/
  571. char        input_buffer[80];      /*                 */
  572. short        input_value;           /*                 */
  573. /*********************************************************************/
  574.   cprintf(M_17);               /* Query and get the master   */
  575.   gets(input_buffer);               /*  volume value          */
  576.   if (sscanf(input_buffer,           /* If user typed value then   */
  577.       "%d",&input_value) == 1)         /*   use it else use default  */
  578.   {                       /*                 */
  579.     if ((input_value >= 0) &&           /* If inputted value is valid */
  580.     (input_value <= 120))           /*                 */
  581.     {                       /*                 */
  582.       master_volume = input_value;     /* Use it             */
  583.     }                       /*                 */
  584.   }                       /*                 */
  585.   cprintf(M_20);               /* Query and get the balance  */
  586.   gets(input_buffer);               /*  setting             */
  587.   if (sscanf(input_buffer,           /*                 */
  588.       "%d",&input_value) == 1)         /*                            */
  589.   {                       /*                 */
  590.     if ((input_value >= 0) &&           /*                 */
  591.     (input_value <= 100))           /*                 */
  592.     {                       /*                 */
  593.       balance = 100 - input_value;     /*                 */
  594.     }                       /*                 */
  595.   }                       /*                 */
  596.   return;                   /*                 */
  597. }                       /* End Function             */
  598. /*********************************************************************/
  599. /*                                     */
  600. /*********************************************************************/
  601. /*********************************************************************/
  602. /*********************************************************************/
  603. /*                                     */
  604. /* FUNCTION NAME = Write_Error_Message                     */
  605. /*                                     */
  606. /* FUNCTION = Determine and write error message to user          */
  607. /*                                     */
  608. /* INPUT =  AAPI return code                         */
  609. /*                                     */
  610. /* OUTPUT = Message written to standard out (user)             */
  611. /*                                     */
  612. /*********************************************************************/
  613. /*********************************************************************/
  614. /*                   CODE                     */
  615. /*********************************************************************/
  616. /*********************************************************************/
  617. static void Write_Error_Message(rc)    /* Begin Function         */
  618. short rc;                   /* Return code             */
  619. {                       /*                 */
  620. /********************LOCAL VARIABLE DEFINITIONS***********************/
  621. char *msg;                   /* Ptr to error message         */
  622. char default_error;               /* Default error case T/F     */
  623. /*********************************************************************/
  624.     default_error = FALSE;           /*                 */
  625.     switch (rc)                /* Case of error code         */
  626.     {                       /*                 */
  627.       case AAPI_RC_08 :            /*                 */
  628.       case AAPI_RC_13 :            /* Insufficient storage         */
  629.       case AAFB_RC_04 :            /*  to complete operation     */
  630.       case AAFB_RC_05 :            /*                 */
  631.       case AAPI_RC_37 :            /*                 */
  632.     msg = M_3;               /*                 */
  633.       break;                   /*                 */
  634.       case AAFB_RC_01 :            /* File already exists         */
  635.     msg = M_4;               /*  and a create requested    */
  636.       break;                   /*                 */
  637.       case AAFB_RC_02 :            /* File doesn't exist         */
  638.     msg = M_5;               /*  and an open requested     */
  639.       break;                   /*                 */
  640.       case AAFB_RC_03 :            /* I/O error on audio file    */
  641.       case AAFB_RC_06 :            /*                 */
  642.       case AAFB_RC_08 :            /*                 */
  643.       case AAPI_RC_01 :            /*                 */
  644.       case AAPI_RC_02 :            /*                 */
  645.       case AAPI_RC_03 :            /*                 */
  646.       case AAPI_RC_04 :            /*                 */
  647.       case AAPI_RC_05 :            /*                 */
  648.       case AAPI_RC_06 :            /*                 */
  649.     msg = M_6;               /*                 */
  650.       break;                   /*                 */
  651.       case AAFB_RC_07 :            /* I/O error on escape file   */
  652.       case AAPI_RC_07 :            /*                 */
  653.       case AAPI_RC_11 :            /*                 */
  654.       case AAPI_RC_19 :            /*                 */
  655.     msg = M_7;               /*                 */
  656.       break;                   /*                 */
  657.       case AAPI_RC_12 :            /* DSP not responding         */
  658.     msg = M_8;               /*                 */
  659.       break;                   /*                 */
  660.       case AAPI_RC_14 :            /* DSP code not found         */
  661.     msg = M_9;               /*                 */
  662.       break;                   /*                 */
  663.       case AAPI_RC_15 :            /* DSP code file invalid      */
  664.     msg = M_10;               /*                 */
  665.       break;                   /*                 */
  666.       case AAPI_RC_24 :            /*                 */
  667.       case AAPI_RC_25 :            /* Audio card not         */
  668.     msg = M_11;               /*  installed             */
  669.       break;                   /*                 */
  670.       case AAPI_RC_26 :            /* Device driver not         */
  671.     msg = M_12;               /*  responding             */
  672.       break;                   /*                 */
  673.       case AAPI_RC_34 :            /* MIDI not allowed in         */
  674.     msg = M_15;               /*  DOS or on channel A         */
  675.       break;                   /*                 */
  676.       case AAPI_RC_29 :            /* Can not play stereo or     */
  677.     msg = M_19;               /*  HQ music with other types */
  678.       break;                   /*                 */
  679.       case AAPI_RC_33 :            /* DSP running and requested  */
  680.     msg = M_21;               /*  oper requires DSP reload  */
  681.       break;                   /*                 */
  682.       case AAPI_RC_09 :            /* Start or stop position     */
  683.       case AAPI_RC_10 :            /* Invalid             */
  684.     msg = M_18;               /*                 */
  685.       break;                   /*                 */
  686.       default :                /* Else case             */
  687.     msg = M_13;               /*                 */
  688.     default_error = TRUE;           /*                 */
  689.       break;                   /*                 */
  690.     }                       /* End Switch             */
  691.     if (default_error)               /* If error that we don't     */
  692.     {                       /*  have a message for,         */
  693.       cprintf(msg,rc);               /* Tell user the return code  */
  694.     }                       /*                 */
  695.     else                   /* Else                 */
  696.     {                       /*                 */
  697.       cprintf(msg);               /* Normal message         */
  698.     }                       /* Endif              */
  699.     return;                   /* Return to caller         */
  700. }                       /* End Function             */
  701. /*********************************************************************/
  702.